package com.lineage.server.datatables;

import com.lineage.DatabaseFactory;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1Teleport;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1ServerQuestMob;
import com.lineage.server.utils.PerformanceTimer;
import com.lineage.server.utils.SQLUtil;
import com.lineage.server.world.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ServerQuestMobTable {
  private static final Log _log = LogFactory.getLog(ServerQuestMobTable.class);
  
  private static ServerQuestMobTable _instance;
  
  private static final HashMap<Integer, HashMap<Integer, L1ServerQuestMob>> _questMobList = new HashMap<>();
  
  public static ServerQuestMobTable get() {
    if (_instance == null)
      _instance = new ServerQuestMobTable(); 
    return _instance;
  }
  
  private ServerQuestMobTable() {
    load();
  }
  
  private void load() {
    PerformanceTimer timer = new PerformanceTimer();
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      con = DatabaseFactory.get().getConnection();
      pstm = con.prepareStatement("SELECT * FROM `w_狩猎怪物任务`");
      rs = pstm.executeQuery();
      while (rs.next()) {
        int quest_id = rs.getInt("quest_id");
        int quest_step = rs.getInt("quest_step");
        String note = rs.getString("note");
        int lv = rs.getInt("lv");
        int[] mob_id = getArray(rs.getString("mob_id"));
        int[] mob_count = getArray(rs.getString("mob_count"));
        int[] item_id = getArray(rs.getString("item_id"));
        int[] item_lv = getArray(rs.getString("item_lv"));
        int[] item_count = getArray(rs.getString("item_count"));
        int save_quest_order = rs.getInt("save_quest_step");
        int tele_x = rs.getInt("tele_x");
        int tele_y = rs.getInt("tele_y");
        int tele_m = rs.getInt("tele_m");
        int tele_delay = rs.getInt("tele_delay");
        int addexp = rs.getInt("addexp");
        L1ServerQuestMob serverQuestMob = new L1ServerQuestMob();
        serverQuestMob.set_quest_id(quest_id);
        serverQuestMob.set_quest_step(quest_step);
        serverQuestMob.set_note(note);
        serverQuestMob.set_lv(lv);
        serverQuestMob.set_mob_id(mob_id);
        serverQuestMob.set_mob_count(mob_count);
        serverQuestMob.set_item_id(item_id);
        serverQuestMob.set_item_lv(item_lv);
        serverQuestMob.set_item_count(item_count);
        serverQuestMob.set_save_quest_order(save_quest_order);
        serverQuestMob.set_tele_x(tele_x);
        serverQuestMob.set_tele_y(tele_y);
        serverQuestMob.set_tele_m(tele_m);
        serverQuestMob.set_tele_delay(tele_delay);
        serverQuestMob.setaddexp(addexp);
        HashMap<Integer, L1ServerQuestMob> questMap = _questMobList
          .get(Integer.valueOf(quest_id));
        if (questMap == null) {
          questMap = new HashMap<>();
          questMap.put(Integer.valueOf(quest_step), serverQuestMob);
          _questMobList.put(Integer.valueOf(quest_id), questMap);
          continue;
        } 
        questMap.put(Integer.valueOf(quest_step), serverQuestMob);
      } 
      _log
        .info("载入[改写]狩猎任务设置资料数量: " + _questMobList.size() + "(" + timer.get() + "ms)");
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
  }
  
  public void getQuestMobNote(L1PcInstance pc) {
    if (_questMobList == null)
      return; 
    Iterator<Integer> iterator = _questMobList.keySet().iterator();
    while (iterator.hasNext()) {
      Integer quest_id = iterator.next();
      if (pc.getQuest().isStart(quest_id.intValue())) {
        HashMap<Integer, L1ServerQuestMob> map = _questMobList.get(quest_id);
        Iterator<Integer> iterator2 = map.keySet().iterator();
        while (iterator2.hasNext()) {
          Integer quest_order = iterator2.next();
          if (pc.getQuest().get_step(quest_id.intValue()) == quest_order.intValue()) {
            int[] mob_id = ((L1ServerQuestMob)map.get(quest_order)).get_mob_id();
            int[] mob_count = ((L1ServerQuestMob)map.get(quest_order)).get_mob_count();
            int[] pc_mob_count = pc.getQuest().get_mob_count(quest_id.intValue());
            if (mob_id.length == mob_count.length) {
              StringBuffer stringBuffer = new StringBuffer();
              stringBuffer.append(String.valueOf(String.valueOf(((L1ServerQuestMob)map.get(quest_order)).get_note())) + "\n");
              int i = 0;
              while (i < mob_id.length) {
                String npc_name = NpcTable.get().getTemplate(mob_id[i]).get_name();
                stringBuffer.append(
                    String.valueOf(String.valueOf(npc_name)) + "(" + pc_mob_count[i] + "/" + mob_count[i] + ")\n");
                i++;
              } 
              pc.sendPackets((ServerBasePacket)new S_ServerMessage(stringBuffer.toString(), 11));
              continue;
            } 
            if (mob_count.length != 1)
              continue; 
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(String.valueOf(String.valueOf(((L1ServerQuestMob)map.get(quest_order)).get_note())) + 
                  "\n 该区域任意怪物(" + pc_mob_count[0] + "/" + mob_count[0] + ")", 11));
          } 
        } 
      } 
    } 
  }
  
  public synchronized void checkQuestMob(L1PcInstance pc, int mobId) {
    if (_questMobList == null)
      return; 
    Iterator<Integer> iterator = _questMobList.keySet().iterator();
    while (iterator.hasNext()) {
      Integer quest_id = iterator.next();
      HashMap<Integer, L1ServerQuestMob> questMap = _questMobList.get(quest_id);
      cheakQuest(quest_id.intValue(), mobId, pc, questMap);
      if (pc.getQuest().isStart(quest_id.intValue()))
        checkMob(quest_id.intValue(), mobId, pc, questMap); 
    } 
  }
  
  private void cheakQuest(int quest_id, int mobId, L1PcInstance pc, HashMap<Integer, L1ServerQuestMob> questMap) {
    if (!pc.getQuest().isStart(quest_id)) {
      Iterator<L1ServerQuestMob> iterator = questMap.values().iterator();
      while (iterator.hasNext()) {
        L1ServerQuestMob serverQuestMob = iterator.next();
        int[] mobid = serverQuestMob.get_mob_id();
        if (pc.getLevel() + pc.getMeteLevel() * 99 < serverQuestMob.get_lv())
          return; 
        if (pc.getQuest().get_step(quest_id) == serverQuestMob.get_save_quest_order())
          return; 
        int i = 0;
        while (i < (serverQuestMob.get_mob_id()).length) {
          if (mobid[i] == mobId && pc.getQuest().get_step(quest_id) == 1)
            pc.getQuest().set_step(quest_id, serverQuestMob.get_quest_step()); 
          i++;
        } 
      } 
      if (pc.isInParty()) {
        Object[] pcs = pc.getParty().partyUsers().values().toArray();
        if (pcs.length <= 0)
          return; 
        Object[] array;
        int length = (array = pcs).length;
        int k = 0;
        while (k < length) {
          Object obj = array[k];
          if (obj instanceof L1PcInstance) {
            L1PcInstance tgpc = (L1PcInstance)obj;
            if (pc != tgpc && World.get().getVisibleObjects((L1Object)pc, (L1Object)tgpc) && 
              !tgpc.getQuest().isStart(quest_id)) {
              Iterator<L1ServerQuestMob> iterator2 = questMap.values().iterator();
              while (iterator2.hasNext()) {
                L1ServerQuestMob serverQuestMob2 = iterator2.next();
                if (tgpc.getLevel() + tgpc.getMeteLevel() * 99 < serverQuestMob2.get_lv())
                  return; 
                if (tgpc.getQuest().get_step(quest_id) == serverQuestMob2.get_save_quest_order())
                  return; 
                int[] mobid2 = serverQuestMob2.get_mob_id();
                int j = 0;
                while (j < (serverQuestMob2.get_mob_id()).length) {
                  if (mobid2[j] == mobId) {
                    tgpc.getQuest().set_step(quest_id, serverQuestMob2.get_quest_step());
                    if (tgpc.getQuest().isStart(quest_id))
                      checkMob(quest_id, mobId, tgpc, questMap); 
                  } 
                  j++;
                } 
              } 
            } 
          } 
          k++;
        } 
      } 
    } 
  }
  
  private void checkMob(int quest_id, int mobId, L1PcInstance pc, HashMap<Integer, L1ServerQuestMob> questMap) {
    Iterator<Integer> iterator = questMap.keySet().iterator();
    while (iterator.hasNext()) {
      Integer quest_step = iterator.next();
      if (pc.getQuest().get_step(quest_id) == quest_step.intValue()) {
        L1ServerQuestMob quest = questMap.get(quest_step);
        if (pc.getLevel() + pc.getMeteLevel() * 99 < quest.get_lv())
          return; 
        int[] mob_id = quest.get_mob_id();
        int[] mob_count = quest.get_mob_count();
        int[] pc_mob_count = pc.getQuest().get_mob_count(quest_id);
        int mustMobCountLength = 0;
        boolean mustMobCountOnly = false;
        if (mob_id.length == mob_count.length) {
          int i = 0;
          while (i < mob_id.length) {
            if (mobId == mob_id[i] && pc_mob_count[i] < mob_count[i]) {
              String npc_name = NpcTable.get().getTemplate(mob_id[i]).get_name();
              pc.getQuest().add_mob_count(quest_id, i);
              get().getQuestMobNote(pc);
            } 
            if (pc_mob_count[i] == mob_count[i])
              mustMobCountLength++; 
            i++;
          } 
        } else if (mob_count.length == 1) {
          int i = 0;
          while (i < mob_id.length) {
            if (mobId == mob_id[i] && pc_mob_count[0] < mob_count[0]) {
              pc.getQuest().add_mob_count(quest_id, 0);
              get().getQuestMobNote(pc);
            } 
            if (pc_mob_count[0] == mob_count[0])
              mustMobCountOnly = true; 
            i++;
          } 
        } 
        if (mustMobCountLength == mob_count.length) {
          StringBuilder stringBuilder = new StringBuilder();
          int[] arrayOfInt1 = quest.get_item_id();
          int[] arrayOfInt2 = quest.get_item_lv();
          int[] arrayOfInt3 = quest.get_item_count();
          int i = quest.getaddexp();
          if (quest.getaddexp() > 0) {
            pc.addExp(i);
            pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励经验:"));
            pc.sendPackets((ServerBasePacket)new S_SystemMessage("狩猎奖励经验值获得:" + i));
          } 
          int k = 0;
          while (k < arrayOfInt1.length) {
            L1ItemInstance item = ItemTable.get().createItem(arrayOfInt1[k]);
            if (item != null) {
              item.setCount(arrayOfInt3[k]);
              if (arrayOfInt2[k] != 0)
                item.setEnchantLevel(arrayOfInt2[k]); 
              if (pc.getInventory().checkAddItem(item, arrayOfInt3[k]) == 0) {
                pc.getInventory().storeItem(item);
                pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励物品:"));
              } else {
                item.set_showId(pc.get_showId());
                World.get().getInventory(pc.getX(), pc.getY(), pc.getMapId()).storeItem(item);
                pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励物品:"));
              } 
              if (stringBuilder.length() != 0)
                stringBuilder.append("\n\r"); 
              pc.sendPackets((ServerBasePacket)new S_ServerMessage(403, item.getLogName()));
            } else {
              _log.error("狩猎任务给予物件失败 原因: 指定编号物品不存在(" + arrayOfInt1 + ")");
            } 
            k++;
          } 
          int m = quest.get_save_quest_order();
          if (m != 0) {
            pc.getQuest().set_mob_count(quest_id, pc.getQuest().get_step(quest_id));
            pc.getQuest().set_step(quest_id, m);
          } 
          int n = quest.get_tele_x();
          int i1 = quest.get_tele_y();
          int i2 = quest.get_tele_m();
          int i3 = quest.get_tele_delay();
          if (n != 0 && i1 != 0 && i2 >= 0) {
            if (i3 != 0)
              try {
                Thread.sleep(i3);
              } catch (InterruptedException e) {
                e.printStackTrace();
              }  
            L1Teleport.teleport(pc, n, i1, (short)i2, 5, true);
          } 
        } 
        if (!mustMobCountOnly)
          continue; 
        StringBuilder name = new StringBuilder();
        int[] item_id = quest.get_item_id();
        int[] item_lv = quest.get_item_lv();
        int[] item_count = quest.get_item_count();
        int addexp = quest.getaddexp();
        if (quest.getaddexp() > 0) {
          pc.addExp(addexp);
          pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励经验:"));
          pc.sendPackets((ServerBasePacket)new S_SystemMessage("狩猎奖励经验值获得:" + addexp));
        } 
        int j = 0;
        while (j < item_id.length) {
          L1ItemInstance item = ItemTable.get().createItem(item_id[j]);
          if (item != null) {
            item.setCount(item_count[j]);
            if (item_lv[j] != 0)
              item.setEnchantLevel(item_lv[j]); 
            if (pc.getInventory().checkAddItem(item, item_count[j]) == 0) {
              pc.getInventory().storeItem(item);
              pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励物品:"));
            } else {
              item.set_showId(pc.get_showId());
              World.get().getInventory(pc.getX(), pc.getY(), pc.getMapId()).storeItem(item);
              pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\fT完成了狩猎任务,奖励物品:"));
            } 
            if (name.length() != 0)
              name.append("\n\r"); 
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(403, item.getLogName()));
          } else {
            _log.error("狩猎任务给予物件失败 原因: 指定编号物品不存在(" + item_id + ")");
          } 
          j++;
        } 
        int step = quest.get_save_quest_order();
        if (step != 0) {
          pc.getQuest().set_mob_count(quest_id, pc.getQuest().get_step(quest_id));
          pc.getQuest().set_step(quest_id, step);
        } 
        int x = quest.get_tele_x();
        int y = quest.get_tele_y();
        int tomapid = quest.get_tele_m();
        int delay = quest.get_tele_delay();
        if (x == 0 || y == 0 || tomapid < 0)
          continue; 
        if (delay != 0)
          try {
            Thread.sleep(delay);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }  
        L1Teleport.teleport(pc, x, y, (short)tomapid, 5, true);
      } 
    } 
  }
  
  private static int[] getArray(String s) {
    StringTokenizer st = new StringTokenizer(s, ",");
    int iSize = st.countTokens();
    String sTemp = null;
    int[] iReturn = new int[iSize];
    int i = 0;
    while (i < iSize) {
      sTemp = st.nextToken();
      iReturn[i] = Integer.parseInt(sTemp);
      i++;
    } 
    return iReturn;
  }
  
  public int[] getMobCount(int quest_id, int quest_order) {
    if (_questMobList.containsKey(Integer.valueOf(quest_id)) && (
      (HashMap)_questMobList.get(Integer.valueOf(quest_id)))
      .containsKey(Integer.valueOf(quest_order))) {
      int length = (((L1ServerQuestMob)((HashMap)_questMobList.get(Integer.valueOf(quest_id)))
        .get(Integer.valueOf(quest_order))).get_mob_count()).length;
      int[] data = new int[length];
      return data;
    } 
    return null;
  }
  
  public Set<Integer> getQuestMobListId() {
    if (_questMobList != null)
      return _questMobList.keySet(); 
    return null;
  }
}
